package gui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Observable;
import java.util.Observer;

import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;

import command.Command;
import command.CommandBroadcaster;
import command.CommandGenerator;

import core.Constants;
import core.Player;
import core.TurnUtil;

/**
 * The top panel of the main frame. The purpose of this panel is to show important information
 * such as Gold, Mana, Achivements, and the time that is left on the turn. Another thing this
 * panel is used for is general menu buttons, might possible add more buttons to this panel
 * for game related purposes.
 * @author Oscar
 *
 */
@SuppressWarnings("serial")
public class StatusPanel extends JPanel implements Observer, ActionListener {
	public static StatusPanel me;

	private JPanel westPanel;
	private JPanel centerPanel;
	private JPanel eastPanel;

	private JLabel gold;
	private JLabel mana;
	private JLabel player;
	private JLabel timeLeftOnTurn;
	private JButton turnButton;
	private BorderLayout thisLayout;

	public static StatusPanel getInstance(){
		if(me == null)
			me = new StatusPanel();
		return me;
	}

	public StatusPanel(){
		init();
	}

	private void init(){
		setBackground(Color.red);
		
		westPanel = new JPanel();
		centerPanel = new JPanel();
		eastPanel = new JPanel();

		gold = new JLabel(ImageHandler.getInstance().getImageIcon("gold.png"));
		gold.setForeground(Color.white);
		
		mana = new JLabel(ImageHandler.getInstance().getImageIcon("mana.png"));
		mana.setForeground(Color.white);
		
		player = new JLabel();
		player.setForeground(Color.white);
		
		timeLeftOnTurn = new JLabel();
		timeLeftOnTurn.setForeground(Color.white);
		
		turnButton = new JButton("End Turn");

		thisLayout = new BorderLayout();
		this.setLayout(thisLayout);

		add(westPanel, BorderLayout.WEST);
		westPanel.add(gold);
		westPanel.add(mana);

		add(centerPanel, BorderLayout.CENTER);
		centerPanel.add(player);
		centerPanel.add(timeLeftOnTurn);
		centerPanel.add(turnButton);

		turnButton.addActionListener(this);

		setVisible(true);
		setOpaque(true);
		repaint();
	}

	/**
	 * Update the panel depending on the status of the player. This includes gold,
	 * mana, achievements. The timeLeftOnTurn graphical appearance is also reseted
	 * with this variable.
	 * @param p
	 */
	private void updateStatus(Player p){
		gold.setText("" + p.getGold()+ "(+" + TurnUtil.getGoldIncome(p) + ")");
		mana.setText("" + p.getMana() + "(+" + TurnUtil.getManaIncome(p) + ")");
		player.setText("Player " + p.getName() + " ");
		timeLeftOnTurn.setText("Time left: " + formatTime(Constants.TURNTIME));
		
		setBackgroundColor(p.getColor());
		
		this.updateUI();
		this.repaint();
	}
	
	/**
	 * Updates the timeLeftOnTurn label .
	 * @param i
	 */
	private void updateTime(int i){
		timeLeftOnTurn.setText("Time left: " + formatTime(i));
		
		this.updateUI();
		this.repaint();
	}
	
	/**
	 * Formats the time, from seconds only to minutes and seconds.
	 * @param t
	 * @return
	 */
	private String formatTime(int t){
		int minutes = 0;
		int seconds = 0;
		
		for(int i = 60; i <= t;){
			minutes += 1;
			t -= 60;
		}
		seconds = t;
		return (String)(minutes+":"+seconds);
	}
	
	/**
	 * Sets the background color of the whole Status panel.
	 * @param c
	 */
	private void setBackgroundColor(Color c){
		westPanel.setBackground(c);
		centerPanel.setBackground(c);
		eastPanel.setBackground(c);
	}

	@Override
	public void update(Observable obs, Object obj) {
		if(obj instanceof Player)
			updateStatus((Player)obj);
		else if(obj instanceof Integer)
			updateTime((Integer)obj);
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		if(e.getSource()==turnButton){
			Command c = CommandGenerator.getInstance().generateEndTurnCommand();
			if(c != null)
				CommandBroadcaster.sendCommand(c);
		}
	}
}
